home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 10 Scripting / 01 Berger / PTNode.H < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-14  |  5.8 KB  |  228 lines

  1. #ifndef __PTNode_H__
  2. #define __PTNode_H__
  3.  
  4.  
  5. #include <string>
  6. #include <vector>
  7.  
  8. #include "SmartPtr.H"
  9.  
  10. // This file defines all the various parse tree (or PT) nodes that are used by
  11. // the compiler.  Every parse tree contains the same basic structure:  a type
  12. // and a set of children.  Because of this, the base parse tree class, PTNode,
  13. // has an enumeration which describes the type of parse tree node, and an
  14. // array of children.
  15. //
  16. // Since most parse tree nodes will have a very fixed number of children
  17. // (e.g., binary operators will always have two children), it is convient to
  18. // derive utility classes from this base parse tree node.  This also has the
  19. // advantage of hiding the parse tree enumeration from the parser, and
  20. // constructors can be used to full effect.
  21.  
  22.  
  23. // The parser tends to through around pointers a lot.  Instead of having to
  24. // keep track of when to delete memory, define a bunch of smart pointers.
  25. // Since these smart pointers are reference counted, they will delete the
  26. // memory automatically.
  27. typedef SmartPtr<class PTNode> PTNodePtr;
  28. typedef SmartPtr<class AddNode> AddNodePtr;
  29. typedef SmartPtr<class SubtractNode> SubtractNodePtr;
  30. typedef SmartPtr<class MultiplyNode> MultiplyNodePtr;
  31. typedef SmartPtr<class DivideNode> DivideNodePtr;
  32. typedef SmartPtr<class ConstantNode> ConstantNodePtr;
  33. typedef SmartPtr<class StatementNode> StatementNodePtr;
  34. typedef SmartPtr<class BlockNode> BlockNodePtr;
  35.  
  36.  
  37. // Define a typedef that will keep track of the set of children nodes that a
  38. // parse tree node can contain.
  39. using namespace std;
  40. typedef vector<PTNodePtr> NodeList;
  41.  
  42.  
  43. // Define the enumeration for the parse tree node types.  Every type of parse
  44. // tree requires a unique type in here.
  45. enum PTNodeType {
  46.   Undef_PTNodeType,
  47.  
  48.   Add_PTNodeType,
  49.   Subtract_PTNodeType,
  50.   Multiply_PTNodeType,
  51.   Divide_PTNodeType,
  52.  
  53.   Constant_PTNodeType,
  54.  
  55.   Statement_PTNodeType,
  56.   Block_PTNodeType
  57. };
  58.  
  59.  
  60.  
  61. // Below are the various parse tree nodes that are used by the compiler.  Only
  62. // the root node contains the type enumeration and the set of children.
  63. // Derived classes simply override the constructor to allow easy construction
  64. // of the specific nodes.  They also add any helpful utiltiy functions for the
  65. // code generator to use.
  66.  
  67. class PTNode : public RefCount {
  68. public:
  69.   PTNode( PTNodeType type )
  70.   {
  71.     m_type = type;
  72.   }
  73.  
  74.   virtual string GetName() const = 0;
  75.  
  76.   void Add( PTNodePtr node )
  77.   {
  78.     m_children.push_back( node );
  79.   }
  80.  
  81.   PTNodeType GetType() const
  82.   {
  83.     return m_type;
  84.   }
  85.  
  86.   // This dump function writes to stdout the enitre contents of this parse
  87.   // tree.
  88.   void Dump() const;
  89.  
  90.  
  91. protected:
  92.   // The code generator needs to be able to iterate over the children that are
  93.   // contains in this parse tree node.  Define a few accessors so it can get
  94.   // to the iterators.
  95.   friend class CodeGen;
  96.  
  97.   NodeList::const_iterator GetChildrenBegin() const
  98.   {
  99.     return m_children.begin();
  100.   }
  101.  
  102.   NodeList::const_iterator GetChildrenEnd() const
  103.   {
  104.     return m_children.end();
  105.   }
  106.  
  107.  
  108. protected:
  109.   // This function is called recursively by Dump() to dump the entire contents
  110.   // of the parse tree.  'indent' is the current indentation level.
  111.   void Dump_Internal( int indent ) const;
  112.  
  113.   // Define the two data members for the parse tree:  The type and the set of
  114.   // children for this node.
  115.   PTNodeType m_type;
  116.   NodeList m_children;
  117. };
  118.  
  119.  
  120.  
  121. // The binary operator node is not used directly by the parser.  This class
  122. // just defines some functions that are in common with all binary operators.
  123. class BinOpNode : public PTNode {
  124. public:
  125.   BinOpNode( PTNodeType type, PTNodePtr lhs, PTNodePtr rhs )
  126.     : PTNode( type )
  127.   {
  128.     Add( lhs );
  129.     Add( rhs );
  130.   }
  131.  
  132.   const PTNodePtr GetLHS() const                  { return m_children[0]; }
  133.   const PTNodePtr GetRHS() const                  { return m_children[1]; }
  134. };
  135.  
  136.  
  137. class AddNode : public BinOpNode {
  138. public:
  139.   AddNode( PTNodePtr lhs, PTNodePtr rhs )
  140.     : BinOpNode( Add_PTNodeType, lhs, rhs )
  141.   {
  142.   }
  143.  
  144.   virtual string GetName() const                  { return "Add"; }
  145. };
  146.  
  147.  
  148. class SubtractNode : public BinOpNode {
  149. public:
  150.   SubtractNode( PTNodePtr lhs, PTNodePtr rhs )
  151.     : BinOpNode( Subtract_PTNodeType, lhs, rhs )
  152.   {
  153.   }
  154.  
  155.   virtual string GetName() const                  { return "Subtract"; }
  156. };
  157.  
  158.  
  159. class MultiplyNode : public BinOpNode {
  160. public:
  161.   MultiplyNode( PTNodePtr lhs, PTNodePtr rhs )
  162.     : BinOpNode( Multiply_PTNodeType, lhs, rhs )
  163.   {
  164.   }
  165.  
  166.   virtual string GetName() const                  { return "Multiply"; }
  167. };
  168.  
  169.  
  170. class DivideNode : public BinOpNode {
  171. public:
  172.   DivideNode( PTNodePtr lhs, PTNodePtr rhs )
  173.     : BinOpNode( Divide_PTNodeType, lhs, rhs )
  174.   {
  175.   }
  176.  
  177.   virtual string GetName() const                  { return "Divide"; }
  178. };
  179.  
  180.  
  181. // The constant node needs to also keep track of the constant that was
  182. // specified in script.  This is done with the data member 'm_value'.
  183. class ConstantNode : public PTNode {
  184. public:
  185.   ConstantNode( int value )
  186.     : PTNode( Constant_PTNodeType ),
  187.       m_value( value )
  188.   {
  189.   }
  190.  
  191.   int GetValue() const                            { return m_value; }
  192.  
  193.   virtual string GetName() const;
  194.  
  195.  
  196. private:
  197.   int m_value;
  198. };
  199.  
  200.  
  201. class StatementNode : public PTNode {
  202. public:
  203.   StatementNode( PTNodePtr expr )
  204.     : PTNode( Statement_PTNodeType )
  205.   {
  206.     Add( expr );
  207.   }
  208.  
  209.   const PTNodePtr GetExpression() const           { return m_children[0]; }
  210.  
  211.   virtual string GetName() const                  { return "Statement"; }
  212. };
  213.  
  214.  
  215. class BlockNode : public PTNode {
  216. public:
  217.   BlockNode( PTNodePtr stmt )
  218.     : PTNode( Block_PTNodeType )
  219.   {
  220.     Add( stmt );
  221.   }
  222.  
  223.   virtual string GetName() const                  { return "Block"; }
  224. };
  225.  
  226.  
  227. #endif // __PTNode_H__
  228.